package lixp.security.service;

import lixp.pojo.UpmsPermission;
import lixp.pojo.UpmsRole;
import lixp.pojo.UpmsUser;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * 在UserDetailService中自定义加载用户信息，
 * 并将用户角色role相关的所有Permissions设置到Authentication的authorities中以供PermissionEvaluator对用户权限进行判断。
 */
@Service
public class MyDetailService implements UserDetailsService {

    Logger logger = LoggerFactory.getLogger(MyDetailService.class);

    @Autowired
    SecurityService securityService;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        UpmsUser upmsUser = securityService.getUpmUserByUserName(username);

        if (upmsUser == null) {
            throw new UsernameNotFoundException("用户名不存在");
        }
        List<UpmsRole> roles = securityService.selectUpmsRoleByUpmsUserId(upmsUser.getUserId());

        List<GrantedAuthority> grantedAuthorities = new ArrayList<>();

        for (UpmsRole role : roles) {
            //将角色添加入用户信息中
            SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority("ROLE_"+role.getName());
            logger.info("角色------------->" + role.getName());
            grantedAuthorities.add(simpleGrantedAuthority);
            //将用户角色所对应的权限添加入用户信息中
            logger.info("role---------->" + role.getRoleId().toString());
            List<UpmsPermission> permissions = securityService.selectUpmsPermissionByRoleId(role.getRoleId());
            for (UpmsPermission upmsPermission : permissions) {
                if (StringUtils.isNotBlank(upmsPermission.getPermissionValue())) {
                    logger.error(upmsPermission.getPermissionValue());
                    /**
                     * 如果不用对hasPermission()，进行处理，那只需要加载用户的相关的permission
                     * 因为hasPermission()，中有两个参数，一个是资源，一个是资源对应的权限
                     * 因此这里进行存储的时候需要将资源（uri）和资源对应的权限（PermissionValue），都放进去
                     * 所以这里需要构成一个对象UrlGrantedAuthority，去实现GrantedAuthority接口
                     *
                     */
                    GrantedAuthority grantedAuthority = new UrlGrantedAuthority(upmsPermission.getUri(),upmsPermission.getPermissionValue());
                    grantedAuthorities.add(grantedAuthority);
                }
            }
        }
        /**
         * 这里的User对象用的是框架中提供的org.springframework.security.core.userdetails.User
         * 其本事实现了UserDetails接口，因此可以直接返回
         */
        return new User(upmsUser.getUsername(), upmsUser.getPassword(), grantedAuthorities);

    }
}
